/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.beautycenter.ModelosTabela;

import br.com.beautycenter.Funcionalidades.Biometria.VariaveisBiometria;
import br.com.beautycenter.Funcionalidades.Biometria.VerificarDigital;
import br.com.beautycenter.Funcionalidades.Data;
import br.com.beautycenter.Funcionalidades.Validacoes;
import br.com.beautycenter.DAO.PersisteFuncionario;
import br.com.beautycenter.DAO.PersisteCliente;
import br.com.beautycenter.DAO.PersistePacoteTratamento;
import br.com.beautycenter.DAO.PersisteSessao;
import br.com.beautycenter.DAO.PersisteTipoTratamento;
import br.com.beautycenter.DAO.PersisteTratamento;
import br.com.beautycenter.Relatorios.ChamadaRelatorios;
import br.com.beautycenter.bean.Funcionario;
import br.com.beautycenter.bean.PacoteTratamento;
import br.com.beautycenter.bean.Sessao;
import br.com.beautycenter.bean.TipoTratamento;
import br.com.beautycenter.bean.Tratamento;
import br.com.beautycenter.view.CadastroPacoteTratamento;
import com.digitalpersona.onetouch.DPFPGlobal;
import com.digitalpersona.onetouch.capture.DPFPCapture;
import com.digitalpersona.onetouch.capture.event.DPFPReaderStatusAdapter;
import com.digitalpersona.onetouch.capture.event.DPFPReaderStatusEvent;
import com.digitalpersona.onetouch.capture.event.DPFPReaderStatusListener;
import com.toedter.calendar.JDateChooser;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;
import org.joda.time.DateTime;

/**
 *
 * @author magelinha
 */
public class TableModelPacoteTratamento extends AbstractTableModel {
    
    private List<Sessao> listaSessoes;
    PersisteTratamento persisteTratamento = new PersisteTratamento();
    PersisteFuncionario persisteFuncionario = new PersisteFuncionario();
    PersisteCliente persisteCliente = new PersisteCliente();
    PersisteSessao persisteSessao = new PersisteSessao();
    PersistePacoteTratamento persistePacote = new PersistePacoteTratamento();
    PersisteTipoTratamento persisteTipo = new PersisteTipoTratamento();
    ChamadaRelatorios chamadaRelatorios = new ChamadaRelatorios();
    
    PacoteTratamento pacoteTratamento;
    int tipoPacote = 0;
    boolean editable;
    
    JFrame parent;
    public static boolean presenca = false;
    
    private String[] colunas = new String[]{"*","Nº","Funcionário","Procedimento","Data","Horário",
                                            "Valor", "Pgto. Efetuado","Indicacão",
                                            "Presença", "Biometria"};
    
    private static final int SELECIONAR = 0;
    private static final int SESSAO = 1;
    private static final int FUNCIONARIO = 2;
    private static final int TRATAMENTO_REALIZADO = 3;
    private static final int DATA = 4;
    private static final int HORARIO = 5;
    private static final int VALOR_SESSAO = 6;
    private static final int PAGAMENTO_EFETUADO = 7;
    private static final int INDICACAO = 8;
    private static final int PRESENCA = 9;
    private static final int BIOMETRIA = 10;
    
    private final URL CAMINHO_ICON = getClass().getResource("/br/com/beautycenter/img/digital.png");
    private final ImageIcon ICON_BIOMETRIA = new ImageIcon(CAMINHO_ICON);
    
    //se o metodo biometria for 0, então a presença vai ser dada com o aparelho.
    private int metodoBiometria;
    
    public static DPFPCapture capturar = DPFPGlobal.getCaptureFactory().createCapture();
    
    public TableModelPacoteTratamento(PacoteTratamento pacoteTratamento) {
        listaSessoes = new ArrayList<Sessao>();
        this.pacoteTratamento = pacoteTratamento;
        confirmarValoresPacote();
        inicializarBiometria();
    }
    
    public void inicializarBiometria(){
        capturar.addReaderStatusListener(new DPFPReaderStatusAdapter(){

            @Override
            public void readerConnected(DPFPReaderStatusEvent e) {
                metodoBiometria = 0;
            }

            @Override
            public void readerDisconnected(DPFPReaderStatusEvent e) {
                metodoBiometria = 1;
            }
        });
        
        try{
            capturar.startCapture();
        }catch (Exception ex){
            System.out.println("erro");
        }
        
    }
    
    public void finalizarBiometria(){
        if(capturar.isStarted()) capturar.stopCapture(); //so para se estiver ligada
    }

    public TableModelPacoteTratamento(JFrame parent, List<Sessao> lista, PacoteTratamento pacoteTratamento, int tipo,
            boolean editable) {
        this.parent = parent;
        this.editable = editable;
        listaSessoes = new ArrayList<Sessao>(lista);
        this.pacoteTratamento = pacoteTratamento;
        confirmarValoresPacote();
        tipoPacote = tipo;
        
        inicializarBiometria();
    }
    
    /**
     * Percorre a lista e define o total a pagar e o total pago
     */
    public void confirmarValoresPacote(){
        PacoteTratamento temp = persistePacote.retornarPacotePeloID(pacoteTratamento);
        
        pacoteTratamento.setTotalPacote(somatorioTotalPacote());
        pacoteTratamento.setTotalPago(somatorioPago());
        
        //se temp for null indica que o pacote de tratamento ainda não foi salvo
        if(temp != null){
            pacoteTratamento = persistePacote.retornarPacotePeloID(pacoteTratamento); //retorna o pacote do banco
            pacoteTratamento.setTotalPacote(somatorioTotalPacote()); //atualiza o total
            pacoteTratamento.setTotalPago(somatorioPago()); //atualiza o total pago
            persistePacote.atualizar(pacoteTratamento); //atualiza o pacote
            persisteCliente.atualizarCreditoCliente(pacoteTratamento.getCliente()); //atualiza o crédito do cliente
        }
        
    }

    @Override
    public int getRowCount() {
        return listaSessoes.size();
    }

    @Override
    public int getColumnCount() {
        return colunas.length;
    }

    @Override
    public Object getValueAt(final int rowIndex, int columnIndex) {
        switch(columnIndex){
            case SELECIONAR:
                return listaSessoes.get(rowIndex).isAlteracao();
                
            case SESSAO:
                return listaSessoes.get(rowIndex).getNumeroSessao();
                
            case TRATAMENTO_REALIZADO:
                if(listaSessoes.get(rowIndex).getTratamento() == null) return "";
                return listaSessoes.get(rowIndex).getTratamento().getNomeTratamento(); 
                
            case DATA:
                if(listaSessoes.get(rowIndex).getDtSessao() == null) return "";
                return Data.formatoDataConvencional.format(listaSessoes.get(rowIndex).getDtSessao());
                
            case VALOR_SESSAO:
                return listaSessoes.get(rowIndex).getValorSessao();
                
            case PAGAMENTO_EFETUADO:
                return listaSessoes.get(rowIndex).getPagamentoEfetuado();
                
            case FUNCIONARIO:
                if(listaSessoes.get(rowIndex).getFuncionario() == null) return "";
                return listaSessoes.get(rowIndex).getFuncionario().getNome();
                
            case INDICACAO:
                if(listaSessoes.get(rowIndex).getIndicacao() == null) return "";
                return listaSessoes.get(rowIndex).getIndicacao().getNome();
                
            case PRESENCA:
                return listaSessoes.get(rowIndex).isPresenca();
                
            case BIOMETRIA:
                JButton botao = new JButton(ICON_BIOMETRIA);
                botao.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if(metodoBiometria == 0) verificarPresencaComBiometria(rowIndex);
                        else verificarPresencaSemBiometria(rowIndex);
                    }
                });
                
                return botao;
                
            case HORARIO:
                if(listaSessoes.get(rowIndex).getHorario() != null) return Data.horaSimpels.format(listaSessoes.get(rowIndex).getHorario());
                return "  :  ";
                
            default:
                throw new IndexOutOfBoundsException("Não é possivel pegar o valor da coluna desejada");
        }
    }
    
    @Override
    public String getColumnName(int columnIndex){
        return colunas[columnIndex];
    }
    
    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex){
        Sessao sessao = listaSessoes.get(rowIndex);
        switch(columnIndex){
            case SELECIONAR:
                sessao.setAlteracao((Boolean)aValue);
                break;
            
            case SESSAO:
                sessao.setNumeroSessao((Integer) aValue);
                break;
            
            case TRATAMENTO_REALIZADO:
                Tratamento tratamento = new Tratamento();
                tratamento.setNomeTratamento(aValue.toString());
                tratamento = persisteTratamento.retornarTratamentoPeloNome(tratamento).get(0);
                
                sessao.setTratamento(tratamento);
                sessao.setValorSessao(tratamento.getValorTratamento());
                break;
            
            case DATA:
                Date data;
                try {
                    if(aValue == null) break;
                    
                    data = Data.formatoDataConvencional.parse(aValue.toString());
                    //verifica se a data é inferior a data atual
                    if(Validacoes.validarDataMaior(data) && !sessao.isPresenca()){
                        JOptionPane.showMessageDialog(null, "A data não pode ser anterior a data atual");
                        break;
                    }
                    
                    sessao.setDtSessao(data);
                } catch (ParseException ex) {
                    JOptionPane.showMessageDialog(null, "Valor informado é inválido!");
                }
                
                
                break;
            case VALOR_SESSAO:
                sessao.setValorSessao((Double)aValue);
                break;
            
            case PAGAMENTO_EFETUADO:
                //se a data de hoje for maior
                if(!Data.validarDataMaior(new DateTime(), new DateTime(sessao.getDtSessao().getTime()))) {
                    JOptionPane.showMessageDialog(null, "Não é possível alterar o valor pago para uma sessão que houve falta. "
                            + "Para realizar essa operação, crie um novo recebimento extra informando esta sessão.");
                    break;
                }
                
                Double numero = (Double)aValue;
                if(numero.compareTo(new Double(0.)) < 0) {
                    JOptionPane.showMessageDialog(null, "O valor deve ser maior que R$ 0,00");
                    break;
                } //se for menor que zero não faz nada
                sessao.setPagamentoEfetuado((Double)aValue);
                break;
                
            case FUNCIONARIO:
                Funcionario funcionario = new Funcionario();
                funcionario.setNome(aValue.toString());
                funcionario = persisteFuncionario.retornarFuncionarioPeloNome(funcionario).get(0);
                
                sessao.setFuncionario(funcionario);
                break;
                
            case INDICACAO:
                Funcionario indicacao = new Funcionario();
                indicacao.setNome(aValue.toString());
                indicacao = persisteFuncionario.retornarFuncionarioPeloNome(indicacao).get(0);
                
                sessao.setIndicacao(indicacao);
                break;
                
            case PRESENCA:
                sessao.setPresenca((Boolean)aValue);
                break;
            
            case HORARIO:
                Date horario;
                if(getValueAt(rowIndex, FUNCIONARIO).equals("")) {
                    JOptionPane.showMessageDialog(null, "Selecione um funcionario.");
                    break;
                }
                if(aValue == null || aValue.toString().replaceAll("_", " ").equals("  :  "))break; //se estiver vazio não faz nada
                try {
                    horario = Data.horaSimpels.parse(aValue.toString());
                    if(!validarHorario(horario,rowIndex)) break;
                    
                    sessao.setHorario(horario);
                } catch (ParseException ex) {
                    JOptionPane.showMessageDialog(null, "Valor informado é inválido!");
                }
                break;
                
            default:
                throw new IndexOutOfBoundsException("Não é possivel pegar o valor da coluna desejada");
        }
        
        if(columnIndex == TRATAMENTO_REALIZADO){
            fireTableCellUpdated(rowIndex, VALOR_SESSAO);
        }
        
        fireTableCellUpdated(rowIndex, columnIndex); // Notifica a atualização da célula
    }
    
    
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex){

        if(!editable) return false;
        
        if((Boolean) getValueAt(rowIndex, PRESENCA)) return false;
        
        
        switch(columnIndex){
            case SELECIONAR:
                return true;
                
            case SESSAO:
                return false;
                
            case TRATAMENTO_REALIZADO:
                return true;
                
            case DATA:
                return true;
                
            case VALOR_SESSAO:
                return false;
                
            case PAGAMENTO_EFETUADO:
                return false;
                
            case FUNCIONARIO:
                return true;
            
            case INDICACAO:
                return true;
                
            case PRESENCA:
                return false;
                
            case BIOMETRIA:
                return true;
                
            case HORARIO:
                return true;
                
            default:
                throw new IndexOutOfBoundsException("Coluna não existe na tabela");
        }
    }
    
    @Override
    public Class<?> getColumnClass(int columnIndex){
        switch(columnIndex){
            case SELECIONAR:
                return Boolean.class;
                
            case SESSAO:
                return Integer.class;
                
            case TRATAMENTO_REALIZADO:
                return JComboBox.class;
                
            case DATA:
                return JDateChooser.class;
                
            case VALOR_SESSAO:
                return Double.class;
                
            case PAGAMENTO_EFETUADO:
                return Double.class;
                
            case FUNCIONARIO:
                return JComboBox.class;
                
            case INDICACAO:
                return JComboBox.class;
                
            case PRESENCA:
                return Boolean.class;
                
            case BIOMETRIA:
                return JButton.class;
                
            case HORARIO:
                return JFormattedTextField.class;
                
            default:
                throw new IndexOutOfBoundsException("Coluna não existe na tabela " + columnIndex);
        }
    }
    
    /*
     * Metodos para manipulação de dados
     */
    
    /**
     * Pega a sessão selecionada na tabela
     * @param linha 
     */
    public Sessao getSessao(int linha){
        return listaSessoes.get(linha);
    }
    
    public void addSessao(Sessao sessao){
        listaSessoes.add(sessao);
        
        int ultimo = getRowCount()-1;
        
        fireTableRowsInserted(ultimo, ultimo);
    }
    
    /**
     * Remove uma determinada linha da tabela
     */
    public void removeSessao(int linha){
        CadastroPacoteTratamento.inseriu -= listaSessoes.get(linha).getValorSessao();
        CadastroPacoteTratamento.alterouPagamentoEfetuado -= listaSessoes.get(linha).getPagamentoEfetuado();
        listaSessoes.remove(linha);
        
        fireTableRowsDeleted(linha, linha);
    }
    
    public void addListaSessoes(List<Sessao> lista){
        int indice = getRowCount();
        
        listaSessoes.addAll(lista);
        
        fireTableRowsInserted(indice, indice + lista.size());
    }
    
    public void clear(){
        listaSessoes.clear();
        fireTableDataChanged();
    }
    
    /**
     * Esse método é chamado quando se clica no botão dentro da tabela. Irá abrir uma janela com a validação
     * da biometria.
     */
    public final void verificarPresencaComBiometria(int rowIndex){
        
        //como ainda não temos o aparelho para testar, faremos algo geérico aqui
        VariaveisBiometria biometria = new VariaveisBiometria(listaSessoes.get(rowIndex).getPacoteTratamento().getCliente());
        VerificarDigital dialog = new VerificarDigital(parent, biometria.getTemplates(), VariaveisBiometria.farRequested.getNumber().intValue());
        dialog.setVisible(true);
        
        if(presenca) listaSessoes.get(rowIndex).setPresenca(presenca);
        
        presenca = false;
        
        fireTableRowsUpdated(rowIndex, rowIndex);
    }
    
    /**
     * Esse método é chamado quando se clica no botão dentro da tabela. Irá abrir uma mensagem de confirmação
     * alertando que o aparelho está desligado e se deseja de fato confirmar a presença do cliente.
     */
    public final void verificarPresencaSemBiometria(int rowIndex){
        
        int resposta = JOptionPane.showConfirmDialog(null, "O aparelho de biometria está desligado ou desconectado. "
                + "Deseja confirmar a presença do cliente mesmo assim?", "Confirmar presente sem biometria", 
                JOptionPane.YES_NO_CANCEL_OPTION);
        
        /**
         * Se responder sim, então confirma a presença
         */
        if(resposta == JOptionPane.YES_OPTION){
            listaSessoes.get(rowIndex).setPresenca(true);
        }
        
        fireTableRowsUpdated(rowIndex, rowIndex);
    }
    
    
    
    //atualiza no banco de dados
    public void salvarBD(){
        if(!validarTabela()) return;
        
        PacoteTratamento temp = persistePacote.retornarPacotePeloID(pacoteTratamento);
        
        //Caso seja um novo pacote salva o pacote e as sessões.
        if(temp == null){
            persistePacote.salvar(pacoteTratamento);
            for(Sessao item: listaSessoes){
                item.setPacoteTratamento(pacoteTratamento);
                persisteSessao.salvar(item);
            }
            
        }else{
            //Caso seja a atualização de um pacote exclui tudo e salva tudo de novo.
            for(Sessao item: temp.getListaSessoes()){
                item = persisteSessao.retornarSessaoPeloID(item);
                persisteSessao.deletar(item);
            }

            for(Sessao item: listaSessoes){
                persisteSessao.atualizar(item);
            }
        }
        
        finalizarPacote();
        
        confirmarValoresPacote();
        imprimirRelatorio(true);
    }
    
    public void finalizarPacote(){
        if(somatorioPago() == somatorioTotalPacote()) {
            pacoteTratamento.setQuitado(true);
            persistePacote.atualizar(pacoteTratamento);
        }
    }
    
    /**
     * Retorna o nome do tipo do pacote
     * 
     * 1 --- pacote de tratamento
     * 2 --- pilates
     * 3 --- laser
     * 4 --- avulso
     * 
     * @param tipoPacote
     * @return 
     */
    public String retornarNomeTipoPacote(int tipoPacote){
       switch(tipoPacote){
           case 1: return "Pacote de Tratamento";
           case 2: return "Pilates";
           case 3: return "Laser";
           case 4: return "Avulso";
           default: return "Pacote de Tratamento";
       } 
    }
    
    public void imprimirRelatorio(boolean pergunta){
        if(pergunta){
            int resposta = JOptionPane.showConfirmDialog(null, "Deseja imprimir o comprovante de pacote?", 
                "Imprimir Relatório", JOptionPane.YES_NO_OPTION);
        
            if(resposta == JOptionPane.YES_OPTION){
                chamadaRelatorios.comprovantePacote(pacoteTratamento.getCliente(), listaSessoes, 
                        retornarNomeTipoPacote(tipoPacote));
            }
        }else{
            chamadaRelatorios.comprovantePacote(pacoteTratamento.getCliente(), listaSessoes, 
                        retornarNomeTipoPacote(tipoPacote));
        }
        
    }
    
    
    //seleciona todos na tabela
    public void selecionarTodos(){
        for(Sessao item: listaSessoes){
            item.setAlteracao(true);
        }
        
        fireTableDataChanged();
    }
    
    //desmarca todos na tabela
    public void desmarcarTodos(){
        for(Sessao item: listaSessoes){
            item.setAlteracao(false);
        }
        
        fireTableDataChanged();
    }
    
    public void adicionarSessao(){
        Sessao sessao = new Sessao();
        if(listaSessoes.isEmpty()){
            sessao.setNumeroSessao(1);
        }else{
            sessao.setNumeroSessao(listaSessoes.get(listaSessoes.size()-1).getNumeroSessao()+1);
        }
        
        //retorna o primeiro funcionário
        Funcionario funcionario = new Funcionario();
        funcionario.setIdPessoa(1);
        funcionario = persisteFuncionario.retornarFuncionarioPeloID(funcionario);
    
        TipoTratamento tipoTratamento = new TipoTratamento();
        tipoTratamento.setIdTipoTratamento(tipoPacote);
        tipoTratamento = persisteTipo.retornarTipoTratamentoPeloID(tipoTratamento);
        
        //pega o primeiro tratamento do tipo passado como parâmetro
        Tratamento tratamento = new Tratamento();
        tratamento.setTipoTratamento(tipoTratamento);
        tratamento = persisteTratamento.retornarTratamentoPeloTipo(tratamento).get(0);
        
        sessao.setIdSessao(0);
        sessao.setAlteracao(false);
        sessao.setDtSessao(new Date());
        sessao.setFuncionario(funcionario);
        sessao.setPacoteTratamento(pacoteTratamento);
        sessao.setPagamentoEfetuado(0);
        sessao.setValorSessao(tratamento.getValorTratamento());
        sessao.setTratamento(tratamento);
        
        addSessao(sessao);
    }
    
    /**
     * Remevo os que estão marcados na tabela
     */
    public void removerSelecionados(){
        Iterator<Sessao> it = listaSessoes.iterator();
        
        while(it.hasNext()){
            Sessao sessao = it.next();
            if(sessao.isAlteracao()) {
                it.remove();
            }
        }
        
        fireTableDataChanged();
    }
    
    public double somatorioTotalPacote(){
        double soma = 0;
        for(Sessao item: listaSessoes){
            soma += item.getValorSessao();
        }
        
        return soma;
    }
    
    public double somatorioPago(){
        double soma = 0;
        for(Sessao item: listaSessoes){
            soma += item.getPagamentoEfetuado();
        }
        
        return soma;
    }
    
    public double retornarTotalCredito(){
        //pacoteTratamento = persistePacote.retornarPacotePeloID(pacoteTratamento); //atualiza só para garantir
        /*
        BigDecimal pago = new BigDecimal(somatorioPago()).setScale(2, RoundingMode.HALF_EVEN);
        BigDecimal total = new BigDecimal(somatorioTotalPacote()).setScale(2, RoundingMode.HALF_EVEN);
        
        if()
        */
        //return 0.;
        return pacoteTratamento.getCliente().getCredito();
    }
    
    /**
     * O saldo parcial será o total de credito sem a pacote atual no banco de dados, somado ao valor total da lista de sessões corrente.
     * @return 
     */
    public double retornarSaldoParcial(){
        double totalCredito = retornarTotalCredito();
        double valorPacoteAtual = pacoteTratamento.getTotalPacote();
        double totalLista = somatorioTotalPacote();
        
        return totalCredito + valorPacoteAtual - totalLista;
    }
    
    /**
     * 
     * @param columnIndex
     * @return 
     */
    public boolean validarHorario(Date horario, int rowIndex){
        try {
            //verifica se o horáro
            DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT, new Locale("pt", "BR"));
            if(!Data.verificarLimiteHora(horario, format.parse("08:00"), format.parse("21:00"))) {
                JOptionPane.showMessageDialog(null, "A horário da sessão deve ser superior à 08:00 e inferior a 21:00");
                return false;
            }
            
            Sessao sessao = listaSessoes.get(rowIndex);
            
            return validarIndividual(sessao, rowIndex, horario);
        } catch (ParseException ex) {
            System.out.println("erro");
            return false;
        }
    }
    
    /**
     * Válido para pacotes que são individuais (pacote de tratamento, laser e avulso)
     * @return 
     */
    public boolean validarIndividual(Sessao sessao, int columnIndex, Date horario){
        DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT, new Locale("pt", "BR"));
        String horaSessao = format.format(horario);
        if(sessao.getPacoteTratamento().getTipoPacote() != 2){
            //verifica se já existe outro pacote de tratamento nesse horário
            for(Sessao item: persisteSessao.retornarSessoesPelaData(sessao.getDtSessao())){
                //deve ser feita a verificaçao apenas se for do mesmo tipo
                if(sessao.getPacoteTratamento().getTipoPacote() == item.getPacoteTratamento().getTipoPacote()){
                    DateTime hItem = new DateTime(item.getHorario());
                    int qtd = TableModelAgenda.qtdQuadroAPreencher(item.getTratamento().getTempo());
                    System.out.println("qtd: " + qtd);
                    for(int i=0; i< qtd; i++){
                        String horaLista = format.format(hItem.toDate());
                        System.out.println("horaSessao: " + horaSessao);
                        System.out.println("horaLista: " + horaLista);
                        if(horaSessao.equals(horaLista)) {
                            JOptionPane.showMessageDialog(null, "Esse horário já está alocado para outro tratamento");
                            return false;
                        }

                        hItem = hItem.plusMinutes(30);
                    }
                }
            }
        }else{
            //verifica se há mais de 3 no mesmo horario
            int cont = 0;
            for(Sessao item: persisteSessao.retornarSessoesPelaData(sessao.getDtSessao())){
                //deve ser feita a verificaçao apenas se for do mesmo tipo
                if(sessao.getPacoteTratamento().getTipoPacote() == item.getPacoteTratamento().getTipoPacote()){
                    DateTime hItem = new DateTime(item.getHorario());
                    for(int i=0; i< TableModelAgenda.posicaoTabela(item.getTratamento().getTempo())[0]; i++){
                        String horaLista = format.format(item.getHorario());
                        if(horaSessao.equals(horaLista)) {
                            cont++;
                        }

                        hItem = hItem.plusMinutes(30);
                    }
                }
            }
            
            if(cont >= 3){
                JOptionPane.showMessageDialog(null, "Esse hárário já está completo");
                return false;
            }
        }
        
        //verifica se o funcionario que fará o tratamento não estará ocupado com outro tipo de pacote
        for(Sessao item: persisteSessao.retornarSessoesPeloFuncionarioData(sessao)){
            DateTime hItem = new DateTime(item.getHorario());
            for(int i=0; i< TableModelAgenda.posicaoTabela(item.getTratamento().getTempo())[0]; i++){
                String horaItem = format.format(item.getHorario());
                if(horaSessao.equals(horaItem)){
                    JOptionPane.showMessageDialog(null, "No horário informado o funcionário estará em outro processo");
                    return false;
                }
                hItem = hItem.plusMinutes(30);
            }
        }
        
        return true;
    }
    
    /**
     * 
     * @return 
     */
    public boolean validarTabela(){
       for(Sessao item: listaSessoes){
           
           if(item.getFuncionario() == null){
               //se não tiver funcionario selecionado
               JOptionPane.showMessageDialog(null, "Para salvar é necessário que todas as sessões estejam preenchidas com algum funcionário.");
               return false;
           }else if(item.getHorario() == null){
               JOptionPane.showMessageDialog(null, "Para salvar é necessário que todas as sessões estejam preenchidas com seu respectivo horário.");
               return false;
           }else if(item.getTratamento() == null){
               JOptionPane.showMessageDialog(null, "Para salvar é necessário que todas as sessões estejam preenchidas com seu tratamento.");
           }
       }
       
       return true;
        
    }
    
    /**
     * Caso o pacote esteja vazio, ele é removido
     */
    public void verificarPacoteVazio(){
        try{
            //pacoteTratamento = persistePacote.retornarPacotePeloID(pacoteTratamento);
            if(listaSessoes.isEmpty() || pacoteTratamento.getListaSessoes() == null || pacoteTratamento.getListaSessoes().isEmpty()){
                pacoteTratamento = persistePacote.retornarPacotePeloID(pacoteTratamento);

                if(pacoteTratamento.getListaSessoes() == null || pacoteTratamento.getListaSessoes().isEmpty()) persistePacote.deletar(pacoteTratamento);
            }
        }catch(Exception ex){
            
        }
        
    }
    
    public void confirmarRecebimento(Double valorRecebido){
        Double local = new Double(valorRecebido.doubleValue());
        for(Sessao item: listaSessoes){
            //se a sessão não está quitada e o valor recebido é capaz de quita-lo, então esse processo é feito
            if(item.getValorSessao() > item.getPagamentoEfetuado() && 
                    local > 0.0){
                
                if(local >= item.getValorSessao()){
                    item.setPagamentoEfetuado(item.getValorSessao());
                    local = local - item.getValorSessao();
                }else{
                    item.setPagamentoEfetuado(local);
                    local = 0.0;
                    break;
                }
            }
        }
        
        fireTableDataChanged();
        
        if(local > 0) JOptionPane.showMessageDialog(null, "Valor informado é maior que o total do pacote. O troco é de: "
                + "R$ " + Validacoes.formatoMoeda.format(local));
    }
}
